home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 676-700 / 681 / term / source.lha / ToneDial.c < prev    next >
C/C++ Source or Header  |  1992-05-09  |  6KB  |  312 lines

  1. /*
  2. **    $Id: ToneDial.c,v 1.1 92/04/03 20:41:26 olsen Sta Locker: olsen $
  3. **    $Revision: 1.1 $
  4. **    $Date: 92/04/03 20:41:26 $
  5. **
  6. **    Touch-tone® dialing support routines
  7. **
  8. **    Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. **
  11. **    Touch-tone period & cycle values
  12. **
  13. **    Copyright © 1989 by Commodore-Amiga, Inc.
  14. */
  15.  
  16. #include "termGlobal.h"
  17.  
  18.     /* Audio device control. */
  19.  
  20. STATIC struct IOAudio    *Audio,
  21.             *Audio1,
  22.             *Audio2;
  23.  
  24.     /* A couple of reply ports. */
  25.  
  26. STATIC struct MsgPort    *AudioPort,
  27.             *Audio1Port,
  28.             *Audio2Port;
  29.  
  30.     /* Channel allocation scheme is as follow:
  31.      *
  32.      *    - allocate two channels either on the right or
  33.      *      the left side.
  34.      *
  35.      *    - if this fails, allocate two different stereo
  36.      *      channels.
  37.      */
  38.  
  39. STATIC UBYTE Channels[] =
  40. {
  41.     LEFT0F  | LEFT1F,
  42.     RIGHT0F | RIGHT1F,
  43.     LEFT0F  | RIGHT1F,
  44.     RIGHT0F | LEFT1F
  45. };
  46.  
  47.     /* Cheapo square wave. */
  48.  
  49. STATIC BYTE __chip SquareWave[8] =
  50. {
  51.     0,127,127,0,0,-127,-127,0
  52. };
  53.  
  54.     /* Touch tone periods for NTSC machines. */
  55.  
  56. STATIC UWORD NTSC_Periods[16][2] = 
  57. {
  58.     { 475,335 },    /* 0 */
  59.     { 642,370 },    /* 1 */
  60.     { 642,335 },    /* 2 */
  61.     { 642,303 },    /* 3 */
  62.     { 581,370 },    /* 4 */
  63.     { 581,335 },    /* 5 */
  64.     { 581,303 },    /* 6 */
  65.     { 525,370 },    /* 7 */
  66.     { 525,335 },    /* 8 */
  67.     { 525,303 },    /* 9 */
  68.     { 475,370 },    /* * */
  69.     { 475,303 },    /* # */
  70.     { 642,274 },    /* A */
  71.     { 581,274 },    /* B */
  72.     { 525,274 },    /* C */
  73.     { 475,274 },    /* D */
  74. };
  75.  
  76.     /* Touch tone periods for PAL machines. */
  77.  
  78. STATIC UWORD PAL_Periods[16][2] = 
  79. {
  80.     { 471,332 },    /* 0 */
  81.     { 636,367 },    /* 1 */
  82.     { 636,332 },    /* 2 */
  83.     { 636,300 },    /* 3 */
  84.     { 576,367 },    /* 4 */
  85.     { 576,332 },    /* 5 */
  86.     { 576,300 },    /* 6 */
  87.     { 520,367 },    /* 7 */
  88.     { 520,332 },    /* 8 */
  89.     { 520,300 },    /* 9 */
  90.     { 471,367 },    /* * */
  91.     { 471,300 },    /* # */
  92.     { 636,271 },    /* A */
  93.     { 576,271 },    /* B */
  94.     { 520,271 },    /* C */
  95.     { 471,271 }    /* D */
  96. };
  97.  
  98.     /* Length of each tone given in audio cycles. */
  99.  
  100. UWORD Cycles[16][2] = 
  101. {
  102.     { 106,150 },    /* 0 */
  103.     {  96,166 },    /* 1 */
  104.     { 106,204 },    /* 2 */
  105.     { 118,250 },    /* 3 */
  106.     {  96,150 },    /* 4 */
  107.     { 106,184 },    /* 5 */
  108.     { 118,226 },    /* 6 */
  109.     {  96,136 },    /* 7 */
  110.     { 106,166 },    /* 8 */
  111.     { 118,204 },    /* 9 */
  112.     {  96,124 },    /* * */
  113.     { 118,186 },    /* # */
  114.     { 130,304 },    /* A */
  115.     { 130,276 },    /* B */
  116.     { 130,250 },    /* C */
  117.     { 130,226 }    /* D */
  118. };
  119.  
  120.     /* The tone codes we know. */
  121.  
  122. UBYTE *Codes = "0123456789*#ABCD";
  123.  
  124.     /* DeleteTone():
  125.      *
  126.      *    Free the resources allocated for touch-tone dialing.
  127.      */
  128.  
  129. VOID
  130. DeleteTone()
  131. {
  132.     if(Audio2)
  133.     {
  134.         FreeVec(Audio2);
  135.  
  136.         Audio2 = NULL;
  137.     }
  138.  
  139.     if(Audio2Port)
  140.     {
  141.         DeleteMsgPort(Audio2Port);
  142.  
  143.         Audio2Port = NULL;
  144.     }
  145.  
  146.     if(Audio1)
  147.     {
  148.         FreeVec(Audio1);
  149.  
  150.         Audio1 = NULL;
  151.     }
  152.  
  153.     if(Audio1Port)
  154.     {
  155.         DeleteMsgPort(Audio1Port);
  156.  
  157.         Audio1Port = NULL;
  158.     }
  159.  
  160.     if(Audio)
  161.     {
  162.         if(Audio -> ioa_Request . io_Device)
  163.             CloseDevice(Audio);
  164.  
  165.         DeleteIORequest(Audio);
  166.  
  167.         Audio = NULL;
  168.     }
  169.  
  170.     if(AudioPort)
  171.     {
  172.         DeleteMsgPort(AudioPort);
  173.  
  174.         AudioPort = NULL;
  175.     }
  176. }
  177.  
  178.     /* CreateTone():
  179.      *
  180.      *    Allocate the resources required for touch-tone dialing.
  181.      */
  182.  
  183. STATIC BYTE
  184. CreateTone()
  185. {
  186.     if(AudioPort = CreateMsgPort())
  187.     {
  188.         if(Audio = (struct IOAudio *)CreateIORequest(AudioPort,sizeof(struct IOAudio)))
  189.         {
  190.             Audio -> ioa_Request . io_Message . mn_Node . ln_Pri    = 10;
  191.             Audio -> ioa_Data                    = Channels;
  192.             Audio -> ioa_Length                    = sizeof(Channels);
  193.  
  194.             if(!OpenDevice(AUDIONAME,0,Audio,0))
  195.             {
  196.                 Audio -> ioa_Request . io_Command    = CMD_WRITE;
  197.                 Audio -> ioa_Request . io_Flags        = ADIOF_PERVOL;
  198.                 Audio -> ioa_Data            = SquareWave;
  199.                 Audio -> ioa_Length            = 8;
  200.                 Audio -> ioa_Volume            = 32;
  201.  
  202.                 if(Audio1Port = CreateMsgPort())
  203.                 {
  204.                     if(Audio1 = (struct IOAudio *)AllocVec(sizeof(struct IOAudio),MEMF_ANY))
  205.                     {
  206.                         CopyMem(Audio,Audio1,sizeof(struct IOAudio));
  207.  
  208.                         Audio1 -> ioa_Request . io_Message . mn_ReplyPort    = Audio1Port;
  209.                         Audio1 -> ioa_Request . io_Unit                = (APTR)((ULONG)Audio -> ioa_Request . io_Unit & (DMAF_AUD0|DMAF_AUD1));
  210.  
  211.                         if(Audio2Port = CreateMsgPort())
  212.                         {
  213.                             if(Audio2 = (struct IOAudio *)AllocVec(sizeof(struct IOAudio),MEMF_ANY))
  214.                             {
  215.                                 CopyMem(Audio,Audio2,sizeof(struct IOAudio));
  216.  
  217.                                 Audio2 -> ioa_Request . io_Message . mn_ReplyPort    = Audio2Port;
  218.                                 Audio2 -> ioa_Request . io_Unit                = (APTR)((ULONG)Audio -> ioa_Request . io_Unit & (DMAF_AUD2|DMAF_AUD3));
  219.  
  220.                                 return(TRUE);
  221.                             }
  222.                         }
  223.                     }
  224.                 }
  225.             }
  226.         }
  227.  
  228.         DeleteTone();
  229.     }
  230.  
  231.     return(FALSE);
  232. }
  233.  
  234.     /* ToneDial(UBYTE *Number):
  235.      *
  236.      *    Dial a number using touch-tone coding, produce the
  237.      *    sounds using the Amiga audio hardware.
  238.      */
  239.  
  240. BYTE
  241. ToneDial(UBYTE *Number)
  242. {
  243.     WORD i,j;
  244.  
  245.         /* Resources ready? */
  246.  
  247.     if(!Audio)
  248.     {
  249.         if(!CreateTone())
  250.             return(FALSE);
  251.     }
  252.  
  253.         /* Check TV system (i.e. crystal frequency). */
  254.  
  255.     if(GfxBase -> DisplayFlags & PAL)
  256.     {
  257.         for(i = 0 ; i < strlen(Number) ; i++)
  258.         {
  259.             for(j = 0 ; j < 16 ; j++)
  260.             {
  261.                 if(ToUpper(Number[i]) == Codes[j])
  262.                 {
  263.                     Audio1 -> ioa_Cycles    = Cycles[j][0];
  264.                     Audio1 -> ioa_Period    = PAL_Periods[j][0];
  265.  
  266.                     Audio2 -> ioa_Period    = PAL_Periods[j][1];
  267.                     Audio2 -> ioa_Cycles    = Cycles[j][1];
  268.  
  269.                     BeginIO(Audio1);
  270.                     BeginIO(Audio2);
  271.  
  272.                     WaitIO(Audio1);
  273.                     WaitIO(Audio2);
  274.  
  275.                     Delay(8);
  276.  
  277.                     break;
  278.                 }
  279.             }
  280.         }
  281.     }
  282.     else
  283.     {
  284.         for(i = 0 ; i < strlen(Number) ; i++)
  285.         {
  286.             for(j = 0 ; j < 16 ; j++)
  287.             {
  288.                 if(Number[i] == Codes[j])
  289.                 {
  290.                     Audio1 -> ioa_Cycles    = Cycles[j][0];
  291.                     Audio1 -> ioa_Period    = NTSC_Periods[j][0];
  292.  
  293.                     Audio2 -> ioa_Cycles    = Cycles[j][1];
  294.                     Audio2 -> ioa_Period    = NTSC_Periods[j][1];
  295.  
  296.                     BeginIO(Audio1);
  297.                     BeginIO(Audio2);
  298.  
  299.                     WaitIO(Audio1);
  300.                     WaitIO(Audio2);
  301.  
  302.                     Delay(8);
  303.  
  304.                     break;
  305.                 }
  306.             }
  307.         }
  308.     }
  309.  
  310.     return(TRUE);
  311. }
  312.